import type { IDataItem, ICommoditySpecsItem } from './types';

// crypto.randomUUID 生成 uuid
export const createUUId = () => window.crypto.randomUUID()

// 属性值 组合 sku
export const getSkuList = <T>(attrList: T[][]) => {
  return attrList.reduce(
    (total, current) => total.flatMap((t) => current.map((c) => [...t, c])),
    [[]] as T[][]
  )
}

// 简单矩阵
export class Adjoin {
  public vertex
  public quantity
  public adjoinArray: number[]
  constructor(vertex: string[]) {
    // 存储id
    this.vertex = vertex
    this.quantity = vertex.length
    this.adjoinArray = []
    this.init()
  }
  private init() {
    this.adjoinArray = Array.from({ length: this.quantity ** 2 })
  }
  // 根据id获取对应列（行列一致）
  public getVertexRow(id: string) {
    const index = this.vertex.indexOf(id)
    const col = [] as number[]
    this.vertex.forEach((item, i) => {
      col.push(this.adjoinArray[index + this.quantity * i])
    })
    return col
  }
  // 根据id获取列，并去除空值
  public getAdjoinVertexs(id: string) {
    return this.getVertexRow(id)
      .map((item, index) => (item ? this.vertex[index] : ''))
      .filter(Boolean)
  }
  // 根据id设置矩阵的值
  setAdjoinVertexs(id: string, sides: string[]) {
    const index = this.vertex.indexOf(id)
    sides.forEach((item) => {
      const i = this.vertex.indexOf(item)
      this.adjoinArray[index + this.quantity + i] = 1
    })
  }

  // 选择多个id，可选项是各个顶点邻接点的并集
  getRowTotal(ids: string[]) {
    const countArr = ids.map(id => this.getVertexRow(id))
    const adjoinNames = [] as number[]
    this.vertex.forEach((item, index) => {
      const rowTotal = countArr
        .map(value => value[index])
        .reduce((total, current) => {
          total += current || 0
          return total
        }, 0)
      adjoinNames.push(rowTotal)
    });
    return adjoinNames
  }
  // 交集
  getUnions(ids: string[]) {
    const arr = this.getRowTotal(ids)
    return arr
      .map((item, index) => item >= ids.length && this.vertex[index])
      .filter(Boolean)
  }
  // 并集
  getCollection(ids: string[]) {
    const arr = this.getRowTotal(ids)
    return arr
      .map((item, index) => item && this.vertex[index])
      .filter(Boolean)
  }
}

// 商品矩阵
export class ShopAdjoin extends Adjoin {
  public commoditySpecs
  public data
  constructor(commoditySpecs: ICommoditySpecsItem[], data: IDataItem[]) {
    super(commoditySpecs.reduce((total, current) => [
      ...total,
      ...current.list,
    ], [] as string[]))

    this.commoditySpecs = commoditySpecs
    this.data = data
    this.initCommodity()
    this.initSimilar()
  }
  initCommodity() {
    this.data.forEach((item) => {
      this.applyCommodity(item.specs);
    });
  }
  initSimilar() {
    // 获得所有可选项
    const specsOption = this.getCollection(this.vertex);
    this.commoditySpecs.forEach((item) => {
      const res = [] as string[];
      item.list.forEach((value) => {
        if (specsOption.indexOf(value) > -1) res.push(value);
      });
      // 同级点位创建
      this.applyCommodity(res);
    });
  }
  querySpecsOptions(ids: string[]) {
    let res;
    // 判断是否存在选项填一个
    if (ids.some(Boolean)) {
      // 过滤一下选项
      res = this.getUnions(ids.filter(Boolean));
    } else {
      // 兜底选一个
      res = this.getCollection(this.vertex);
    }
    return res;
  }
  applyCommodity(ids: string[]) {
    ids.forEach((id) => {
      this.setAdjoinVertexs(id, ids);
    });
  }
}
